<?php

declare(strict_types=1);

namespace App\Third\Service\Wx;


use App\Common\Constants\ErrorCode;
use App\Common\Service\BaseService;
use App\Common\Constants\Stakeholder;
use App\Order\Service\OrderGoodsService;
use App\Order\Service\OrderService;
use App\Resource\Model\GoodsModel;
use App\Resource\Service\ShopService;
use App\User\Service\AddressService;
use App\User\Service\MemberService;

/**
 * 平台内部服务封装
 * Class WxDeliverService
 * @package App\Third\Service\Wx
 */

class WxDeliverService extends  BaseService
{

    /**
     * POS 吾享外卖退单
     * @param $order_no
     * @param $orderRefundGoods
     * @param $needRefundMoney
     * @param $refundType
     * @param int $partRefundFlg
     * @param string $note
     * @return array
     */
    public function refundedPush($order_no, $orderRefundGoods, $needRefundMoney, $refundType, $partRefundFlg = 0, $note = '')
    {
        $orderInfo = $this->container->get(OrderService::class)->findFirst(['order_no' => $order_no])->toArray();
        $payInfo = $this->getPayInfo($orderInfo, (string)$needRefundMoney);

        $res = $this->common($orderInfo, $orderRefundGoods);
        $goodsListByGoodsId = $res['goodsListByGoodsId'];
        $shopArr = $res['shopArr'];
        $orderGoodsListByGoodsId = $res['orderGoodsListByGoodsId'];

        $deliverRefundGoodsArr = [];
        foreach ($orderRefundGoods as $value) {
            $scant_id = $goodsListByGoodsId[$value['goods_id']]['scant_id'];
            $ratio = $goodsListByGoodsId[$value['goods_id']]['ratio'];
            $goodsDisPrice = $orderGoodsListByGoodsId[$value['goods_id']]['goods_dis_price'];
            if ($scant_id == Stakeholder::GOODS_NON_STANDARD) {
                $qty = bcmul((string)bcdiv((string)$ratio, '1000', 2), (string)$value['goodsNum'], 2);
                $allPrice = bcmul((string)$goodsDisPrice, (string)$value['goodsNum'], 2);
                $goodsPrice = bcdiv($allPrice, $qty, 2);
            }
            if ($scant_id == Stakeholder::GOODS_STANDARD) {
                $qty = $value['goodsNum'];
                $goodsPrice = $goodsDisPrice;
            }
            $deliverRefundGoodsArr[] = [
                "itemCode" => $orderGoodsListByGoodsId[$value['goods_id']]['itemCode'],
                "itemName" => $value['goodsName'],
                "smItemFlg" => 0,
                'qty' => $qty ?? '',
                'pr' => $goodsPrice ?? '',
                'refundItemPrice' => $goodsPrice
            ];
        }
        $temp_data = [
            'mcID' => $shopArr['crm_mcid'],                           //10008,//门店编号
            'deID' => $orderInfo['deId'],                             //'70981',//吾享外卖单ID
            'deNo' => $orderInfo['deNo'],                             //'1203465734990208420022',//吾享外卖单No
            'deFrom' => 3,                                            //外送单来源
            'partRefundFlg' => $partRefundFlg == 1 ? $partRefundFlg : 0,   //字段是PartRefundFlg，商家部分退的时候希望能传1，食客部分退的时候传0
            'refundMoney' => $needRefundMoney,                        //退款总金额
            'reason' => $note,                                        //退单原因
            'refundType' => $refundType,
            'businessNo' => $orderInfo['serial_num'],                 //商家流水号。自提单如果没有商家流水号可以传自提码
            'deItemList' => $deliverRefundGoodsArr,
            'payInfo' => $payInfo
        ];
        $res = $this->container->get(WxMainDeliverService::class)->refundDeliveryOfflineMapping($orderInfo, $temp_data);
        if ($res['code'] == 1){
            if($res['data']['returnCode'] == 1 && $res['data']['errorText'] == '成功'){
                return ['code' => 1, 'msg' => '外卖推送退单成功', 'data' => []];
            }
        }
        return ['code' => 0, 'msg' => '外卖推送退单异常', 'errorCode' => ErrorCode::NOT_IN_FORCE,'errorMsg' => $res['data']['errorText']];

    }
    /**
     * 支付推送
     * @param string $orderNo
     * @return array
     */
    public function payPush(string $orderNo){
        $order = $this->container->get(OrderService::class);
        $orderInfo = $order->findFirst(['order_no' => $orderNo])->toArray();
        if (!empty($orderInfo['deNo']) || !empty($orderInfo['deId'])){
            return ['code' => 0, 'errorCode' => ErrorCode::SYSTEM_INVALID, 'msg' => '重复推送支付外送单'];
        }
        $payInfo = $this->getPayInfo($orderInfo, (string)$orderInfo['total_price']);
        $couponMoney = 0;
        if($orderInfo['coupon_status'] == Stakeholder::ORDER_IS_COUPON_YES){
            $couponMoney = $orderInfo['coupon_cut'];
        }
        if ($orderInfo['deal_type'] == Stakeholder::ORDER_DELIVERY) {
            $userInfo = $this->container->get(AddressService::class)->addressInfo(['id' => $orderInfo['address_id']], ['area','address','username','phone']);
            $dinerName = $userInfo['username'];
            $deAddress = $userInfo['area'] . $userInfo['address'];
            $remark = $orderInfo['memo'] . '-配送时间:' . $orderInfo['appointment_time'];
            $isBook = 1;
        }
        if ($orderInfo['deal_type'] == Stakeholder::ORDER_SELF_PICK) {
            $userInfo = $this->container->get(MemberService::class)->findFirst(['mid' => $orderInfo['mid']], ['nickname','phone'])->toArray();
            $dinerName = $userInfo['nickname'];
            $remark = '自提订单-自提时间:' . $orderInfo['appointment_time'];
            $isBook = 2;
        }
        $dinerPhoneNo = $userInfo['phone'];
        $deBeginTime = date('Y-m-d H:i:s',strtotime($orderInfo['appointment_date'])-3600);
        $deEndTime = $orderInfo['appointment_date'];
        $res = $this->common($orderInfo);
        $orderGoodsArr = $res['orderGoodsArr'];
        $shopArr = $res['shopArr'];
        $goodsListByGoodsId = $res['goodsListByGoodsId'];
        $deliverGoodsArr = [];
        foreach($orderGoodsArr as $value){
            $scant_id = $goodsListByGoodsId[$value['goods_id']]['scant_id'];
            $ratio = $goodsListByGoodsId[$value['goods_id']]['ratio'];
            $itemCode=$goodsListByGoodsId[$value['goods_id']]['wx_crm_code'];
            $unitName = $goodsListByGoodsId[$value['goods_id']]['lsy_unit_name'] ?? '份';
            if($scant_id == Stakeholder::GOODS_NON_STANDARD){
                $qty = ($ratio/1000) * $value['number'];
                if($qty == 0){
                    $qty = 1;
                }
                $selling_price = round(bcmul((string)$value['selling_price'],(string)$value['number'],2)/$qty,2);
            }
            if($scant_id == Stakeholder::GOODS_STANDARD){
                $qty = $value['number'];
                $selling_price = $value['selling_price'];
            }
            $deliverGoodsArr[] = [
                'itemcode' => $itemCode,
                'itemName' => $value['goods_title'],
                'unitName' => $unitName,
                'qty' => $qty ?? '',
                'pr' => $selling_price ?? '',
                'itemRemark' => $value['goods_spec']
            ];
        }
        $temp_data  = [
            'mcID' => $shopArr['crm_mcid'],               //10008,//门店编号  $shopArr['crm_mcid']
            'Openid' => $orderInfo['openid'],             //'33333',//食客openid
            'deFrom' => 3,                                //第三方订单ID
            'dinerName' => $dinerName ?? '',                    //收货人姓名
            'dinerPhoneNo' => $dinerPhoneNo ?? '',              //收货人手机号
            'deAddress' => $deAddress ?? '',                      //收货人地址
            'dePrice' => $orderInfo['freight_price'],     //配送费
            'payBills' => bcadd((string)$orderInfo['goods_price'], (string)$couponMoney, 2),     //点餐总价（折前）
            'payAmount' => $orderInfo['total_price'],    //支付金额（点餐总价（折后） + 配送费）。自提时配送费为0
            'totalprice' => $orderInfo['total_price'],
            'activityTotalFee' => $couponMoney,
            'shopPartFee' => $couponMoney,
            'preferentialContent' => '优惠劵优惠'.$couponMoney,
            'payTypeid' => array_column($payInfo, 'payTypeID')[0] ?? '',
            'State' => 0,                               //外卖单状态（0：等待商户确认；1：商户确认成功；2：商户确认失败；3：线下商户取消；4：外送起送；5：外送送达；6：商家未处理；7：待支付；9：制作中；10：线上食客取消；11：外送平台强制取消）
            'remark' => $remark ?? '',                        //备注
            'sn' => $orderInfo['serial_num'],           //商家流水号。自提单如果没有商家流水号可以传自提码
            'isbook' => $isBook ?? '',                        // 0：立即送达；1：预约时间配送；2：自提
            'deDate' => $orderInfo['appointment_date'],
            'deBeginTime' => $deBeginTime ?? '',
            'deEndTime' => $deEndTime ?? '',
            'deItemList' => $deliverGoodsArr,
            'payInfo' => $payInfo
        ];
        $res = $this->container->get(WxMainDeliverService::class)->deliveryInsertOfflineMapping($orderInfo,$temp_data);
        if ($res['code'] == 1){
            if($res['data']['returnCode'] == 1 && $res['data']['errorText'] == '成功'){
                $order->update(['order_no' => $orderNo], ['deId' => $res['data']['deid'], 'deNo' => $res['data']['deNo'],'pos_type'=>1]);
                return ['code' => 1, 'msg' => '外卖推送下单成功', 'data' => []];
            }
        }
        $order->update(['order_no' => $orderNo], ['pos_type' => 2]);
        return ['code' => 0, 'msg' => '外卖推送下单异常', 'errorCode' => ErrorCode::NOT_IN_FORCE,'errorMsg' => $res['data']['errorText'] ?? $res['msg']];

    }

    /**
     * 共享方法--按需获取
     * @param array $orderInfo
     * @param array|null $orderRefundGoods
     * @return array
     */
    public function common(array $orderInfo, array $orderRefundGoods = null){
        $shopArr = $this->container->get(ShopService::class)
            ->shopInfoByWhere(['shop_id' => $orderInfo['shop_id']], ['crm_mcid', 'lsy_shop_no', 'shop_no']);
        if (!empty($orderRefundGoods)){
            $goodsIds = array_column($orderRefundGoods, 'goods_id');
            $orderGoodsList = $this->container->get(OrderGoodsService::class)
                ->getOrderGoodsList(['order_no' => $orderInfo['order_no']], ['goods_id', 'itemCode', 'dis_price', 'goods_dis_price'], ['goods_id', $goodsIds]);
            $orderGoodsListByGoodsId = array_column($orderGoodsList, null, 'goods_id');
        }else{
            $orderGoodsArr = $this->container->get(OrderGoodsService::class)
                ->getOrderGoodsList(['order_no' => $orderInfo['order_no']], ['goods_id','itemCode','goods_title','number','goods_spec','dis_price','goods_dis_price','selling_price']);
            $goodsIds = array_column($orderGoodsArr, 'goods_id');
        }
        $goodsList = $this->container->get(GoodsModel::class)::query()
            ->select(['id', 'goods_crm_code', 'wx_crm_code','scant_id', 'ratio','lsy_unit_name'])
            ->whereIn('id', $goodsIds)
            ->get()
            ->toArray();
        $goodsListByGoodsId = array_column($goodsList, null, 'id');
        return [
            'orderGoodsArr' => $orderGoodsArr ?? [],
            'goodsListByGoodsId' => $goodsListByGoodsId,
            'orderGoodsListByGoodsId' => $orderGoodsListByGoodsId ?? [],
            'shopArr' => $shopArr
        ];
    }


    /**
     * 支付子信息
     * @param array $orderInfo
     * @param string $payMoney
     * @return array
     */
    protected function getPayInfo(array $orderInfo, string $payMoney) :array {
        $payInfo = [];
        if ($orderInfo['pay_type'] == Stakeholder::PAYMENT_METHOD_WECHAT) {
            $payInfo[] = [
                "payTypeID" => 6,
                "payMoney" => $payMoney,
                "payrealMoney" => $payMoney
            ];
        }
        if ($orderInfo['pay_type'] == Stakeholder::PAYMENT_METHOD_BALANCE) {
            $payInfo[] = [
                "payTypeID" => 3,
                "payMoney" => $payMoney,
                "payrealMoney" => $payMoney
            ];
        }
        return $payInfo;
    }

}